#include <common>
#include <packing>

varying vec2 vUv;
varying vec2 vUv2;
varying vec3 vNormal;
varying vec3 vViewPosition;
varying vec3 vTangent;
varying vec3 vBitangent;

uniform vec3 diffuse;
uniform vec3 emissive;
uniform vec3 specular;
uniform float shininess;
uniform float opacity;


uniform sampler2D map;
uniform sampler2D specularMap;

uniform sampler2D normalMap;
uniform vec2 normalScale;


#include <lights_pars_begin>
#include <bsdfs>

/* Define RenderEquations (RE) */


    struct CustomMaterial {

        vec3 diffuseColor;
        vec3 specularColor;
        float specularShininess;
        float specularStrength;

    };

    void RE_Direct_Custom( const in IncidentLight directLight, const in GeometricContext geometry, const in CustomMaterial material, inout ReflectedLight reflectedLight ) {

        float dotNL = saturate( dot( geometry.normal, directLight.direction ) );
        vec3 irradiance = dotNL * directLight.color;

        reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );

        reflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularShininess ) * material.specularStrength;
        
    }

    void RE_IndirectDiffuse_Custom( const in vec3 irradiance, const in GeometricContext geometry, const in CustomMaterial material, inout ReflectedLight reflectedLight ) {

        reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );

    }

    #define RE_Direct				RE_Direct_Custom
    #define RE_IndirectDiffuse		RE_IndirectDiffuse_Custom

    #define Material_LightProbeLOD( material )	(0)

/* Define RenderEquations (RE) */



void main(void){

    vec4 diffuseColor = vec4( diffuse, opacity );
    ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
	vec3 totalEmissiveRadiance = emissive;

    // map_fragment
    vec4 texelColor = texture2D( map, vUv );

	diffuseColor *= texelColor;


    // specular_fragment
    float specularStrength;

    vec4 texelSpecular = texture2D( specularMap, vUv );
	specularStrength = texelSpecular.r;

    /* normal */

        // normal_fragment_begin
        vec3 normal = normalize( vNormal );
        vec3 tangent = normalize( vTangent );
        vec3 bitangent = normalize( vBitangent );
        mat3 vTBN = mat3( tangent, bitangent, normal );

        vec3 geometryNormal = normal;

        // normal_fragment_maps
        vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;
        mapN.xy *= normalScale;
        normal = normalize( vTBN * mapN );


    
    /* normal */

	/* accumulation */
	
        // lights_phong_fragment
        CustomMaterial material;
        material.diffuseColor = diffuseColor.rgb;
        material.specularColor = specular;
        material.specularShininess = shininess;
        material.specularStrength = specularStrength;

        
        // lights_fragment_begin
        #include <lights_fragment_begin>

        // lights_fragment_maps
        #include <lights_fragment_maps>
        
        // lights_fragment_end
        #include <lights_fragment_end>

    /* accumulation */



    // output_fragment

    vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;
    diffuseColor.a = 1.0;
    gl_FragColor = vec4( outgoingLight, diffuseColor.a );

}